﻿using System.Collections.Generic;
using System.Linq;
using T.FAS.Runtime.Base.Entity;

namespace T.FAS.Runtime.Metadata.Entity.DataModel
{
    public static class DataModelExtension
    {
        /// <summary>
        /// do是否需要清除Database的引用
        /// </summary>
        /// <param name="dataObject"></param>
        public static void ClearRef(this DataObject dataObject)
        {
            //do是否需要清除Database的引用
            dataObject.Database = null;
        }

        /// <summary>
        ///  cdo清空引用
        /// </summary>
        /// <param name="cdo"></param>
        public static void ClearRef(this CompositeDataObject cdo)
        {
            cdo.RootCompositeNodeObject = null;

            //置空需要重构引用关系的属性
            foreach (var cno in cdo.CompositeNodeObjects)
            {
                cno.ParentObject = null;
                cno.CompositeDataObject = null;
                cno.ChildCompositeNodeObjects = null;
                cno.DataObject = null;
                foreach (var ele in cno.Elements)
                {
                    ele.DataColumn = null;
                    ele.StateMachines = null;
                }
                if (cno.Associations != null)
                {
                    foreach (var ass in cno.Associations)
                    {
                        ass.AssoDomaiModel = null;
                        ass.AssoCompositeNodeObject = null;
                        ass.AssoDataObject = null;
                    }
                }
            }
        }

        /// <summary>
        /// dq清空引用
        /// </summary>
        /// <param name="dq"></param>
        public static void ClearRef(this DataQuery dq)
        {
            //权限是否要清空
            //dq.ActionPermission = null;
            if (dq.DataQuerySources != null)
            {
                foreach (var source in dq.DataQuerySources)
                {
                    source.DataObject = null;

                }
            }
            if (dq.DataQueryColumns != null)
            {
                foreach (var col in dq.DataQueryColumns)
                {
                    col.DataObject = null;
                    col.DataColumn = null;
                }
            }
            if (dq.DataQueryJoins != null)
            {
                foreach (var join in dq.DataQueryJoins)
                {
                    join.LeftQuerySource = null;
                    join.RightQuerySource = null;
                }
            }
            if (dq.DataQueryFilters != null)
            {
                foreach (var filter in dq.DataQueryFilters)
                {

                }
            }
            if (dq.DataQuerySorts != null)
            {
                foreach (var sort in dq.DataQuerySorts)
                {
                    sort.DataObject = null;
                    sort.DataColumn = null;
                }
            }
            if (dq.DataQueryParams != null)
            {
                foreach (var param in dq.DataQueryParams)
                {

                }
            }
            if (dq.SubQuerys != null)
            {
                foreach (var sub in dq.SubQuerys)
                {
                    sub.SubQuery = null;
                }
            }
        }

        /// <summary>
        /// eo清空引用
        /// </summary>
        /// <param name="dataObject"></param>
        public static void ClearRef(this EntityObject eo)
        {
            if (eo.EntityObjectAttributes != null)
            {
                foreach (var attr in eo.EntityObjectAttributes)
                {
                    attr.SubEntity = null;
                    attr.SubEntitys = null;
                }
            }
        }

        /// <summary>
        /// sm清空引用
        /// </summary>
        /// <param name="dataObject"></param>
        public static void ClearRef(this StateMachineMetadata sm)
        {
            //权限信息是否需要置空
            //sm.BPO = null;
            sm.CompositeDataObject = null;
            sm.StaticDataObject = null;

            if (sm.States != null)
            {
                //foreach (var stat in sm.States)
                //{
                //}
            }
            if (sm.Events != null)
            {
                foreach (var even in sm.Events)
                {
                    //even.StateMachineEventPermission = null;
                    //even.OP = null;

                }
            }
            if (sm.Transitions != null)
            {
                foreach (var tran in sm.Transitions)
                {
                    tran.From = null;
                    tran.To = null;
                    tran.Event = null;

                    if (tran.Actions != null)
                    {
                        foreach (var action in tran.Actions)
                        {
                            //
                            action.Paramters = null;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 尝试获取
        /// </summary>
        /// <param name="column"></param>
        /// <param name="dataQuery"></param>
        /// <returns></returns>
        public static bool TryGetDataColumnHelpSetting(this DataQueryColumn column, DataQuery dataQuery, out DataObjectColumnHelpSetting setting)
        {
            setting = null;
            if (column.ColumnType == ColumnType.Express) return false;
            else if (column.ColumnType == ColumnType.Group || column.ColumnType == ColumnType.Aggregate)
            {
                if (!string.IsNullOrEmpty(column.DataQuerySourceID))
                {
                    DataObject dataObject = dataQuery?.DataQuerySources.FirstOrDefault(s => s.ID == column.DataQuerySourceID)?.DataObject;
                    setting = dataObject?.ColumnHelpSettings?.FirstOrDefault(c => c.DataColumnID == column.DataObjectColumnID);
                }
                else
                    return false;
            }
            else
            {
                DataObject dataObject = dataQuery?.DataQuerySources.FirstOrDefault(s => s.ID == column.DataQuerySourceID)?.DataObject;
                setting = dataObject?.ColumnHelpSettings?.FirstOrDefault(c => c.DataColumnID == column.DataObjectColumnID);
            }
            return setting != null;
        }

        /// <summary>
        /// 尝试获取
        /// </summary>
        /// <param name="ele"></param>
        /// <param name="dataQuery"></param>
        /// <returns></returns>
        public static bool TryGetDataColumnHelpSetting(this CompositeNodeObjectElement ele, CompositeNodeObject cno, out DataObjectColumnHelpSetting setting)
        {
            setting = null;
            if (ele == null || cno == null || ele.ElementType != ElementType.Normal) return false;
            setting = cno?.DataObject?.ColumnHelpSettings?.FirstOrDefault(c => c.DataColumnID == ele.DataColumnID);
            return setting != null;
        }
    }

    public static class TSchemaExtension
    {
        public static TAttribute CloneAttr(this TAttribute attribute)
        {
            TAttribute attr = new TAttribute
            {
                MetadataCode = attribute.MetadataCode,
                SourceColumnID = attribute.SourceColumnID,
                SourceColumnCode = attribute.SourceColumnCode,
                SourceColumnName = attribute.SourceColumnName,
                RefSchemaExpr = attribute.RefSchemaExpr,
                ID = attribute.ID,
                Code = attribute.Code,
                Name = attribute.Name,
                Description = attribute.Description,
                DataType = attribute.DataType,
                IsPrimaryKey = attribute.IsPrimaryKey,
                SortOrder = attribute.SortOrder,
                IsDetail = attribute.IsDetail,
                IsVirtual = attribute.IsVirtual,
                RelatePropertyCode = attribute.RelatePropertyCode,
                EntityType = attribute.EntityType,
                Length = attribute.Length,
                IsRequired = attribute.IsRequired,
                Precision = attribute.Precision,
                DefaultValue = attribute.DefaultValue,
                AttributeType = attribute.AttributeType,
                //Entity = attribute.Entity,
                ExtProperties = GetDictCopy(attribute.ExtProperties),
            };
            return attr;
        }

        private static Dictionary<string, object> GetDictCopy(Dictionary<string, object> dict)
        {
            Dictionary<string, object> shallowCopy = new Dictionary<string, object>();
            if (dict != null)
            {
                foreach (var key in dict.Keys)
                {
                    shallowCopy[key] = dict[key];
                }
            }
            return shallowCopy;
        }
    }
}
